package db

import (
	"errors"
	"hr/api/dto"

	"github.com/spf13/cast"
	"gorm.io/gorm"
)

// OfficialSealApproval 公章申请
type OfficialSealApproval struct {
	AppModel
	UserID          string `gorm:"size:64" json:"user_id"`
	Reason          string `json:"reason"`
	CreateBy        string `gorm:"size:128" json:"createBy"`        // 创建人
	UpdateBy        string `gorm:"size:128" json:"updateBy"`        // 更新人
	Remark          string `gorm:"size:255" json:"remark"`          //备注
	OrderStatus     string `gorm:"size:64;" json:"order_status"`    // 申请状态 1保存、2提交
	ApprovalStatus  string `gorm:"size:64;" json:"approval_status"` // 是否同意 1是2否
	RefuseReason    string `json:"refuseReason"`
	SealType        string `gorm:"size:64;" json:"seal_type"`        //公章类型 1公司公章 2财务章 3法人章 4合同章 5名章 6发票
	Mode            string `gorm:"size:64;" json:"mode"`             //申请方式 1带走 2现在盖
	ApplicationTime string `gorm:"size:64;" json:"application_time"` //申请时间
	ReturnTime      string `gorm:"size:64;" json:"return_time"`
}

func (u *OfficialSealApproval) TableName() string {
	return "official_seal_approval"
}

type OfficialSealApprovalName struct {
	OfficialSealApproval
	UserName string `json:"user_name"`
}

type OfficialSealApprovalPageModel struct {
	Total    int64                      `json:"total"`
	Result   []OfficialSealApprovalName `json:"result"`
	PageNo   int                        `json:"pageNo"`
	PageSize int                        `json:"pageSize"`
}

func GetOfficialSealApprovalPaging(pagination dto.Pagination, name string, userId uint, from string) (OfficialSealApprovalPageModel, error) {
	user := GetUserById(userId)
	role := GetRoleById(user.RoleID)
	result := OfficialSealApprovalPageModel{
		Total:    0,
		Result:   make([]OfficialSealApprovalName, 0),
		PageNo:   pagination.PageNo,
		PageSize: pagination.PageSize,
	}
	offset := (pagination.PageNo - 1) * pagination.PageSize
	dbs := GetInstance().Select("official_seal_approval.*,concat(IFNULL(user.name,''),'(',user.nick_name,')') as user_name").Joins("left join user on official_seal_approval.create_by = user.id")

	if from == "1" && role.Code == "small_captain" {
		dbs = dbs.Where("user.dept_id=?", user.DeptID).Where("official_seal_approval.approval_status='3'").Order("official_seal_approval.created_at desc")
	} else {
		if role.Code == "supper" {
			dbs = dbs.Where("official_seal_approval.approval_status!='3'").Order("official_seal_approval.created_at desc")
		} else {
			dbs = dbs.Where("official_seal_approval.create_by = ?", userId).Order("official_seal_approval.created_at desc")
		}
	}

	if err := dbs.Offset(offset).Limit(pagination.PageSize).Find(&result.Result).Error; err != nil {
		return result, err
	}
	if err := dbs.Offset(-1).Limit(-1).Count(&result.Total).Error; err != nil {
		return result, err
	}
	return result, nil
}

func GetOfficialSealApproval(p map[string]interface{}, extra ...interface{}) (OfficialSealApproval, error, string) {
	f := OfficialSealApproval{}
	queryDb := GetInstance().Where(p).First(&f)
	if len(extra) > 0 {
		queryDb = queryDb.Where(extra)
	}
	err := queryDb.Error
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return f, errors.New("查无记录"), "0"
		}
		return f, errors.New(err.Error()), "1"
	}
	return f, nil, "2"
}

func CreateOfficialSealApproval(p OfficialSealApproval, userId string) (OfficialSealApproval, error) {
	approval := p.ApprovalStatus
	if p.OrderStatus == "2" {
		user := GetUserById(cast.ToUint(userId))
		isCaptain := HasSmallCaptain(user.DeptID)
		if isCaptain {
			approval = "3"
		}
	}
	d := OfficialSealApproval{
		UserID:          p.UserID,
		Reason:          p.Reason,
		CreateBy:        userId,
		Remark:          p.Remark,
		OrderStatus:     p.OrderStatus,
		ApprovalStatus:  approval,
		RefuseReason:    p.RefuseReason,
		Mode:            p.Mode,
		SealType:        p.SealType,
		ApplicationTime: p.ApplicationTime,
		ReturnTime:      p.ReturnTime,
	}
	if err := GetInstance().Create(&d).Error; err != nil {
		return d, errors.New("创建失败")
	}
	return d, nil
}

func UpdateOfficialSealApproval(id uint, p OfficialSealApproval, user string) (OfficialSealApproval, error) {
	f := OfficialSealApproval{
		AppModel: AppModel{
			ID: id,
		},
	}
	err := GetInstance().Model(&f).Updates(OfficialSealApproval{
		UserID:          p.UserID,
		Reason:          p.Reason,
		UpdateBy:        user,
		Remark:          p.Remark,
		OrderStatus:     p.OrderStatus,
		ApprovalStatus:  p.ApprovalStatus,
		RefuseReason:    p.RefuseReason,
		Mode:            p.Mode,
		SealType:        p.SealType,
		ApplicationTime: p.ApplicationTime,
		ReturnTime:      p.ReturnTime,
	}).Updates(map[string]interface{}{
		"id": id,
	}).Scan(&f).Error
	if err != nil {
		return f, err
	}
	return f, nil
}

func DeleteOfficialSealApproval(id uint) (OfficialSealApproval, error) {
	f := OfficialSealApproval{}
	err := GetInstance().Unscoped().Where("id = ?", id).Delete(&f).Error
	if err != nil {
		return f, err
	}
	return f, nil
}

func UpdateOfficialSealApprovalOrderStatus(id uint, status string, userId uint) (OfficialSealApproval, error) {
	approval := ""
	if status == "2" {
		user := GetUserById(userId)
		isCaptain := HasSmallCaptain(user.DeptID)
		if isCaptain {
			approval = "3"
		}
	}
	f := OfficialSealApproval{
		AppModel: AppModel{
			ID: id,
		},
	}
	err := GetInstance().Model(&f).Updates(map[string]interface{}{
		"order_status":    status,
		"approval_status": approval,
	}).Scan(&f).Error
	if err != nil {
		return f, err
	}
	return f, nil
}

func UpdateOfficialSealApprovalApprovalStatus(p dto.ApprovalRequest, id uint) (OfficialSealApproval, error) {
	f := OfficialSealApproval{
		AppModel: AppModel{
			ID: id,
		},
	}
	data := make(map[string]interface{})
	data["approval_status"] = p.ApprovalStatus
	data["refuse_reason"] = p.RefuseReason
	err := GetInstance().Model(&f).Updates(data).Scan(&f).Error
	if err != nil {
		return f, err
	}
	return f, nil
}
